package com.css.fxfzysx.modules.vaomeFacilities.service.impl;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.css.fxfzysx.base.response.RestResponse;
import com.css.fxfzysx.constants.FxfzConstants;
import com.css.fxfzysx.modules.cztDataMange.constans.RedisKeyConstants;
import com.css.fxfzysx.modules.cztDataMange.utils.GenerationNumberUtil;
import com.css.fxfzysx.modules.vaomeFacilities.entity.CipHisDamageEntity;
import com.css.fxfzysx.modules.vaomeFacilities.entity.CipvMatrixEntity;
import com.css.fxfzysx.modules.vaomeFacilities.repository.HeDamageRepository;
import com.css.fxfzysx.modules.vaomeFacilities.repository.VmeFacilitiesRepository;
import com.css.fxfzysx.modules.vaomeFacilities.service.ImportDataService;
import com.css.fxfzysx.modules.vaomeFacilities.utils.PinyinAPI;
import com.css.fxfzysx.util.CreateGson;
import com.css.fxfzysx.util.PlatformDateUtils;
import com.css.fxfzysx.util.UUIDGenerator;
import com.css.fxfzysx.web.PlatformSessionContext;
import com.css.fxfzysx.zcpt.sys.entity.SUser;
import com.css.fxfzysx.zcpt.sys.service.SUserService;
import com.css.fxfzysx.zcpt.sys.service.SysRoleService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ImportDataServiceImpl implements ImportDataService {

    @Resource
    private GenerationNumberUtil generationNumberUtil;

    @Autowired
    private VmeFacilitiesRepository vmeFacilitiesRepository;

    @Autowired
    private HeDamageRepository heDamageRepository;

    @Autowired
    private SysRoleService roleService;

    @Autowired
    private SUserService userService;

    @Override
    public RestResponse importMajorProjectsData(MultipartFile file, String type) {
        try {
            String user = userService.getSUser(PlatformSessionContext.getUserID());
            SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<Object> title = reader.readRow(1);
            String titleName = "[序号, 省份, 烈度, 基本完好, 轻微破坏sl, 中等破坏ml, 严重破坏el, 倒塌c, 设防情况, 类型, 年代]";
            if(type.equals("其他重大工程设施")){
                titleName = "[序号, 省份, 烈度, 基本完好, 轻微破坏sl, 中等破坏ml, 严重破坏el, 倒塌c, 设防情况, 重大工程设施名称, 年代]";
            }
            if (!titleName.equals(title.toString())) {
                return RestResponse.fail("导入失败，请检查表头是否改动");
            }
            List<List<Object>> read = reader.read(2, reader.getRowCount());
            if (read.size() == 0) {
                return RestResponse.fail("导入失败，表格中无数据");
            }
            //数据校验
            RestResponse rs = vmOilParameterVerification(read.size(), read);
            if (rs.getCode() != 200) {
                return RestResponse.fail(rs.getMessage());
            }

            ArrayList<CipvMatrixEntity> dataList = new ArrayList<>();
            for (List<Object> objects : read) {
                CipvMatrixEntity cipvMatrixEntity = new CipvMatrixEntity();
                cipvMatrixEntity.setProvince(objects.get(1).toString());
                cipvMatrixEntity.setIntensity(objects.get(2).toString());
                cipvMatrixEntity.setBasicIntact(new BigDecimal(objects.get(3).toString()));
                cipvMatrixEntity.setSlightDamage(new BigDecimal(objects.get(4).toString()));
                cipvMatrixEntity.setModerateDamage(new BigDecimal(objects.get(5).toString()));
                cipvMatrixEntity.setBadlyDamaged(new BigDecimal(objects.get(6).toString()));
                cipvMatrixEntity.setCollapse(new BigDecimal(objects.get(7).toString()));
                cipvMatrixEntity.setFortification(objects.get(8).toString());
                cipvMatrixEntity.setCipvType(objects.get(9).toString());
                cipvMatrixEntity.setYears(objects.get(10).toString());
                if(!VmeFacilitiesServiceImpl.predict(cipvMatrixEntity)){
                    return RestResponse.fail("失败,每行数据之和必须等于1");
                }
                dataList.add(cipvMatrixEntity);
            }
            Map<String, List<CipvMatrixEntity>> collect = dataList.stream().collect(Collectors.groupingBy(
                    score -> score.getFortification() + "-" + score.getYears() + "-" + score.getCipvType()
            ));
            collect.forEach((k, v) -> {
                String number = "";
                String[] split = k.split("-");
                if (type.equals("输油管线") || type.equals("输气管线")) {
                    number = (PinyinAPI.getPinYinHeadChar(split[2]) + "-" + generationNumberUtil.getFs(split[0]) + "-" +
                            generationNumberUtil.getGenerationNumber(type.equals("输油管线") ? RedisKeyConstants.CZT_SY_KEY : RedisKeyConstants.CZT_SQ_KEY));
                }
                if (type.equals("水库大坝")) {
                    number = (PinyinAPI.getPinYinHeadChar(split[2]) + "-" + generationNumberUtil.getFs(split[0]) + "-" +
                            generationNumberUtil.getGenerationNumber(RedisKeyConstants.CZT_SKDB_KEY));
                }
                if (type.equals("其他重大工程设施")) {
                    number = ("QTZDGCSS" + "-" + generationNumberUtil.getFs(split[0]) + "-" +
                            generationNumberUtil.getGenerationNumber(RedisKeyConstants.CZT_QT_KEY));
                }
                String finalNumber = number;
                v.stream().forEach(it -> {
                    it.setCreateUser(PlatformSessionContext.getUserID());
                    it.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                    it.setCipvId(UUIDGenerator.getUUID());
                    it.setUserName(sUser.getUserName());
                    it.setMajorProjectCategory(type);
                    it.setDelFlag("0");
                    it.setCipvCode(finalNumber);
                    vmeFacilitiesRepository.saveData(it);
                });
            });
            return RestResponse.succeed("成功");
        } catch (IOException e) {
            String errorMessage = "导入失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    /**
     * Object转BigDecimal
     *
     * @param value
     * @return
     */
    public static BigDecimal getBigDecimal(Object value) {
        BigDecimal ret = null;
        if (value != null) {
            if (value instanceof BigDecimal) {
                ret = (BigDecimal) value;
            } else if (value instanceof String) {
                ret = new BigDecimal((String) value);
            } else if (value instanceof BigInteger) {
                ret = new BigDecimal((BigInteger) value);
            } else if (value instanceof Number) {
                ret = new BigDecimal(((Number) value).doubleValue());
            } else {
                throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
            }
        }
        return ret;
    }

    private RestResponse vmOilParameterVerification(int size, List<List<Object>> data) {
        for (int i = 0; i < size; i++) {
            List<Object> objects = data.get(i);
            if(objects.size()!=11){
                return RestResponse.fail("请补全数据!");
            }
//            if (StringUtils.isBlank(objects.get(1).toString())) return RestResponse.fail("第" + (i + 3) + "行的{烈度}不能为空！");
//            if (StringUtils.isBlank(objects.get(2).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{基本完好}不能为空！");
//            if (StringUtils.isBlank(objects.get(3).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{轻微破坏sl}不能为空！");
//            if (StringUtils.isBlank(objects.get(4).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{中等破坏ml}不能为空！");
//            if (StringUtils.isBlank(objects.get(5).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{严重破坏el}不能为空！");
//            if (StringUtils.isBlank(objects.get(6).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{倒塌c}不能为空！");
//            if (StringUtils.isBlank(objects.get(7).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{设防情况}不能为空！");
//            if (StringUtils.isBlank(objects.get(8).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{类型}不能为空！");
//            if (StringUtils.isBlank(objects.get(9).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{年代}不能为空！");
        }
        return RestResponse.succeed();
    }

    @Override
    public RestResponse importHeDamageData(MultipartFile file) {
        try {
            String user = userService.getSUser(PlatformSessionContext.getUserID());
            SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<Object> title = reader.readRow(0);
            String titleName = "[序号, 地震动参数(烈度), 破坏状态, 地震名称, 震级, 设防情况, 发生时间, 重大工程类别, 年代]";
            if (!titleName.equals(title.toString())) {
                return RestResponse.fail("导入失败，请检查表头是否改动");
            }
            List<List<Object>> read = reader.read(2, reader.getRowCount());
            if (read.size() == 0) {
                return RestResponse.fail("导入失败，表格中无数据");
            }
            //数据校验
            RestResponse rs = heParameterVerification(read.size(), read);
            if (rs.getCode() != 200) {
                return RestResponse.fail(rs.getMessage());
            }
            ArrayList<CipHisDamageEntity> dataList = new ArrayList<>();
            for (List<Object> objects : read) {
                CipHisDamageEntity cipHisDamageEntity = new CipHisDamageEntity();
                cipHisDamageEntity.setParams(getBigDecimal(objects.get(1)));
                cipHisDamageEntity.setBreakState(objects.get(2).toString());
                cipHisDamageEntity.setSeismName(objects.get(3).toString());
                cipHisDamageEntity.setMagnitude(objects.get(4).toString());
                cipHisDamageEntity.setFortification(objects.get(5).toString());
                SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd");
                cipHisDamageEntity.setSeismTime(dateFormat.parse(objects.get(6).toString()));
                cipHisDamageEntity.setProjectType(objects.get(7).toString());
                cipHisDamageEntity.setYears(objects.get(8).toString());
                dataList.add(cipHisDamageEntity);
            }
            Map<String, List<CipHisDamageEntity>> collect = dataList.stream().collect(Collectors.groupingBy(
                    score -> score.getFortification() + "-" + score.getProjectType()
            ));
            collect.forEach((k, v) -> {
                String[] split = k.split("-");
                String number = ("ZH"+"-"+generationNumberUtil.getFs(split[0]) + "-" +PinyinAPI.getPinYinHeadChar(split[1])+"-"+
                            generationNumberUtil.getGenerationNumber(RedisKeyConstants.CZT_HD_KEY));
                v.stream().forEach(it -> {
                    it.setCreateUser(PlatformSessionContext.getUserID());
                    it.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                    it.setCiphdId(UUIDGenerator.getUUID());
                    it.setDelFlag("0");
                    it.setUserName(sUser.getUserName());
                    it.setCiphdCode(number);
                    heDamageRepository.saveCipHisDamage(it);
                });
            });
            return RestResponse.succeed("导入成功!");
        } catch (IOException | ParseException e) {
            String errorMessage = "导入失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }

    private RestResponse heParameterVerification(int size, List<List<Object>> data) {
        for (int i = 0; i < size; i++) {
            List<Object> objects = data.get(i);
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 3) + "行的{地震动参数(地震动参数(烈度))}不能为空！");
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 3) + "行的{地震动参数(破坏状态)}不能为空！");
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 3) + "行的{地震动参数(地震名称)}不能为空！");
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 3) + "行的{地震动参数(震级)}不能为空！");
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 3) + "行的{地震动参数(设防情况)}不能为空！");
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 3) + "行的{地震动参数(发生时间)}不能为空！");
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 3) + "行的{地震动参数(重大工程类别)}不能为空！");
            if (StringUtils.isBlank(objects.get(1).toString()))
                return RestResponse.fail("第" + (i + 3) + "行的{地震动参数(年代)}不能为空！");
        }
        return RestResponse.succeed();
    }


    @Override
    public RestResponse importNpsData(MultipartFile file) {
        try {
            String user = userService.getSUser(PlatformSessionContext.getUserID());
            SUser sUser = CreateGson.createGson().fromJson(user, SUser.class);
            ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
            List<Object> title = reader.readRow(1);
            String titleName = "[序号, 省份, 烈度, 基本完好, 轻微破坏sl, 中等破坏ml, 严重破坏el, 倒塌c, 设防情况, 类型, 类型, 年代]";
            if (!titleName.equals(title.toString())) {
                return RestResponse.fail("导入失败，请检查表头是否改动");
            }
            List<List<Object>> read = reader.read(2, reader.getRowCount());
            if (read.size() == 0) {
                return RestResponse.fail("导入失败，表格中无数据");
            }
            //数据校验
            RestResponse rs = npsParameterVerification(read.size(), read);
            if (rs.getCode() != 200) {
                return RestResponse.fail(rs.getMessage());
            }
            ArrayList<CipvMatrixEntity> dataList = new ArrayList<>();
            for (List<Object> objects : read) {
                CipvMatrixEntity cipvMatrixEntity = new CipvMatrixEntity();
                cipvMatrixEntity.setProvince(objects.get(1).toString());
                cipvMatrixEntity.setIntensity(objects.get(2).toString());
                cipvMatrixEntity.setBasicIntact(new BigDecimal(objects.get(3).toString()));
                cipvMatrixEntity.setSlightDamage(new BigDecimal(objects.get(4).toString()));
                cipvMatrixEntity.setModerateDamage(new BigDecimal(objects.get(5).toString()));
                cipvMatrixEntity.setBadlyDamaged(new BigDecimal(objects.get(6).toString()));
                cipvMatrixEntity.setCollapse(new BigDecimal(objects.get(7).toString()));
                cipvMatrixEntity.setFortification(objects.get(8).toString());
                cipvMatrixEntity.setCipvType(objects.get(9).toString());
                cipvMatrixEntity.setCipvType1(objects.get(10).toString());
                cipvMatrixEntity.setYears(objects.get(11).toString());
                dataList.add(cipvMatrixEntity);
                if(!VmeFacilitiesServiceImpl.predict(cipvMatrixEntity)){
                    return RestResponse.fail("失败,每行数据之和必须等于1");
                }
            }
            Map<String, List<CipvMatrixEntity>> collect = dataList.stream().collect(Collectors.groupingBy(
                    score -> score.getFortification() + "-" + score.getYears() + "-" + score.getCipvType()+"-"+score.getCipvType1()
            ));
            collect.forEach((k, v) -> {
                String number = "";
                String[] split = k.split("-");
                number = (PinyinAPI.getPinYinHeadChar(split[2]+split[3]) + "-" + generationNumberUtil.getFs(split[0]) + "-" +
                            generationNumberUtil.getGenerationNumber(RedisKeyConstants.CZT_HDZ_KEY));
                String finalNumber = number;
                v.stream().forEach(it -> {
                    it.setCreateUser(PlatformSessionContext.getUserID());
                    it.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
                    it.setCipvId(UUIDGenerator.getUUID());
                    it.setMajorProjectCategory(FxfzConstants.CZT_HD_HDZ);
                    it.setDelFlag("0");
                    it.setUserName(sUser.getUserName());
                    it.setCipvCode(finalNumber);
                    vmeFacilitiesRepository.saveData(it);
                });
            });
            return RestResponse.succeed("成功");
        } catch (IOException e) {
            String errorMessage = "导入失败!";
            log.error(errorMessage, e);
            return RestResponse.fail(errorMessage);
        }
    }


    private RestResponse npsParameterVerification(int size, List<List<Object>> data) {
        for (int i = 0; i < size; i++) {
            List<Object> objects = data.get(i);
            if(objects.size()!=12){
                return RestResponse.fail("请补全数据");
            }
//            if (StringUtils.isBlank(objects.get(1).toString())) return RestResponse.fail("第" + (i + 3) + "行的{烈度}不能为空！");
//            if (StringUtils.isBlank(objects.get(2).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{基本完好}不能为空！");
//            if (StringUtils.isBlank(objects.get(3).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{轻微破坏sl}不能为空！");
//            if (StringUtils.isBlank(objects.get(4).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{中等破坏ml}不能为空！");
//            if (StringUtils.isBlank(objects.get(5).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{严重破坏el}不能为空！");
//            if (StringUtils.isBlank(objects.get(6).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{倒塌c}不能为空！");
//            if (StringUtils.isBlank(objects.get(7).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{设防情况}不能为空！");
//            if (StringUtils.isBlank(objects.get(8).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{类型}不能为空！");
//            if (StringUtils.isBlank(objects.get(9).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{类型}不能为空！");
//            if (StringUtils.isBlank(objects.get(10).toString()))
//                return RestResponse.fail("第" + (i + 3) + "行的{年代}不能为空！");
        }
        return RestResponse.succeed();
    }
}
